// /*
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Library General Public
//    License version 2 as published by the Free Software Foundation.
// 
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Library General Public License for more details.
// 
//    You should have received a copy of the GNU Library General Public License
//    along with this library; see the file COPYING.LIB.  If not, write to
//    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
//    Boston, MA 02110-1301, USA.
// */
// 
// #ifndef MATH_FUNCTION_H
// #define MATH_FUNCTION_H
// #include <string>
// #include <memory>
// 
// #include "Eigen/Core"
// //#include "muparser/muParser.h"
// #include <boost/scoped_array.hpp>
// 
// USING_PART_OF_NAMESPACE_EIGEN
// namespace mu
// {
//     class Parser ; 
// }
// namespace Math {
//     /*!
//      * \brief Enumeration over types of function avaible. 
//      *          Function can exist in only three states
//      */
//     enum FunctionDef
//     {
//         eUnknown=0, /*!< Unknown. When function does not have equation, and no data has been assign */
//         eDiscrete,/*!< Discrete. When function is in fact in Matrix form. */
//         eContinuous /*!< Continuous. When function is given by equation, so matrix is not used*/
//     };
//     enum DerivativeMethod
//     {
//         eFiniteDifferenceTwoPoints=0,
//         eFiniteDifferenceThreePoints,
//         eFiniteDifferenceThreePointsWithScantLine,
//     };
//     class FunctionException : public std::exception {
//         public:
//             FunctionException ( const std::string & _error ) { m_Error="none";}
//             ~FunctionException() throw () {} 
//             virtual const char * what() const throw() { return m_Error.c_str() ; } 
//         private:
//             std::string m_Error ; 
//     };
//     /*!
//      * \author Bartosz.Taczala
//      * \brief class defining 2d function 
//      */
//     class Function2D 
//     {
//         public:
//             /*!
//              * \brief ctor
//              * \param _equation [in] equation of function 
//              * \see setEquation()
//              */
//             Function2D( const std::string & _equation ="") ; 
//             ~Function2D() ; 
//             /*!
//              * \brief set eqution for given func
//              * \param _equation - equation of function 
//              */
//             void                                setEquation ( const std::string & _equation ) ;
//             /*!
//              * \brief return  eqution for given func
//              * \see Function2D()
//              * \return  equation of function 
//              */
//             inline const std::string &          equation( ) const { return m_Equation ; }
//             inline void                         setDescription ( const std::string & _functionName ) { m_FunctionDescription = _functionName ; } 
//             inline const std::string &          description() const { return m_FunctionDescription ; } 
//             /*!
//              * \brief return  type of function. This cannot be modified by user explicitly. 
//              * \see Function2D()
//              * \see setEquation()
//              * \return  type of function
//              */
//             inline FunctionDef                  typeOf() const ; 
//             /*!
//              * \brief Sets data
//              * \param _pX - domain 
//              * \param _pY - range
//              * \param _size - size of allocated memory
//              * \return  value of function in point x
//              *      If this function is called function changes type. It's now eDiscrete.
//              */
//             void                                setData ( double * _pX, double * _pY, int _size ) ; 
//             /*!
//              * \brief Calculates f(x)
//              *      If it cannot be evaluated FunctionException is thrown 
//              * \param _x 
//              * \return  value of function in point x
//              */
//             double                              value( double _x ) const; 
//             
//             /*!
//              * \brief if function is in cintinous form underlaying data ( xs(), ys() ) will be recaluculated
//              * \param _size - new size
//              * \param _xMin - new lower boundary
//              * \param _xMax - new upper boundary
//              * \param _step - new step 
//              */
//             void                                recalculateData ( int _size, double _xMin, double _xMax, double _step ) ; 
//             const double *                      xs() const { return m_Xs.get() ;}
//             const double *                      ys() const { return m_Ys.get() ;}
//             int                                 size() const { return m_SizeOfArrays ; } 
//             /*!
//              * \brief calculates derivative on given area. 
//                      If function is not defined on given area FunctionException is thrown. 
//              * \param _startX - starts from
//              * \param _stopX - ends from
//              * \param step - h, przyrost funkcji
//              * \param _dMethod - method for calculating derivative
//              */
//             Math::Function2D *                  calculateDerivative( double _startX, double _stopX, double _step, DerivativeMethod _dMethod = Math::eFiniteDifferenceTwoPoints ) const ; 
//             
//             bool                                needToRecalculate() const { return m_NeedToRecalculate ;}
//         private:
//             /// fields
//             std::string                         m_Equation ; /*! < equation of function */
//             std::string                         m_FunctionDescription ;/*! < description of function. In most cases it can be equation or " Derivative of sin(x) " 
//             std::auto_ptr<MatrixXd>             m_apMatrixOfValues ; /*! < When function is in discrete form, this cannot be NULL. Otherwise NULL*/
//             FunctionDef                         m_Type ; /*! < type of function*/
//             /// methods 
//             /*! 
//              * \brief wrapper around mu::Parser
//              */
//             class Parser
//             {
//                 public:
//                     Parser( const std::string & _equation="") ;
//                     ~Parser();
//                     double                    evaluate( double _x ) const; 
//                     inline void               setEquation( const std::string & _equation );
//                 private:
//                     std::auto_ptr<mu::Parser> m_pParser ; 
//                     mutable double            m_fVal ; 
//             } m_Parser ; 
//             boost::scoped_array< double >       m_Xs ; 
//             boost::scoped_array< double >       m_Ys ; 
//             int                                 m_SizeOfArrays ; 
//             bool                                m_NeedToRecalculate ; 
//     };
//     class Function3D
//     {
//         ;
//     };
//     
// }
// #endif // MATH_FUNCTION_H